package com.zhuiYun.project.config.jwt;

import com.zhuiYun.project.api.sysUser.entiy.SysUser;
import com.zhuiYun.project.common.errorCode.CommonException;
import com.zhuiYun.project.common.errorCode.EmErrorCode;
import com.zhuiYun.project.util.ObjectUtils;
import com.zhuiYun.project.util.RedisUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.stereotype.Component;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ClassName JWTAuthenticationTokenFilter
 * @Description JWT接口请求校验拦截器
 *               请求接口时会进入这里验证Token是否合法和过期
 * @Author zcy
 * @Date 2023/3/27 16:28
 **/
@Component
@Slf4j
public class JWTAuthenticationTokenFilter extends BasicAuthenticationFilter {



    public JWTAuthenticationTokenFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    /**
     * 验证token
     * @param request
     * @param response
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @SneakyThrows
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        // 获得TokenHeader
        //验证token格式是否正确
        if (JWTUtils.checkRequestToken(request)) {
            // 截取JWT前缀
            String token =JWTUtils.getToken(request);
            // 解析JWT
            boolean verify = JWTUtils.verify(token);
            SysUser sysUser = null;
            try{
                sysUser = (SysUser) RedisUtil.get(token);
            }catch (Exception e){
                e.printStackTrace();
            }
            if(verify&& ObjectUtils.isNotEmpty(sysUser)) {
                // 获取用户名
               // String username = JWTUtils.getInfo(token, "username");
                String loginName = JWTUtils.getInfo(token, "loginName");
                if(ObjectUtils.isNotEmpty(loginName)&&loginName.equals(sysUser.getLoginName())){
                    // 续约token
                    RedisUtil.expire(token,JWTConfig.expiration);
                    RedisUtil.expire(sysUser.getLoginName(),JWTConfig.expiration);
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(sysUser, loginName, null);
                    // 将user对象交给SecurityContextHolder管理
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }else{
                    // token中的loginName 与redis中的不符
                    throw new CommonException(EmErrorCode.TOKEN_INVALID);
                }
//                    if(!StringUtils.isEmpty(username)&&!StringUtils.isEmpty(userId)) {
//                        // 获取角色
//                        List<GrantedAuthority> authorities = new ArrayList<>();
//                        String authority = claims.get("authorities").toString();
//                        if(!StringUtils.isEmpty(authority)){
//                            List<Map<String,String>> authorityMap = JSONObject.parseObject(authority, List.class);
//                            for(Map<String,String> role : authorityMap){
//                                if(!StringUtils.isEmpty(role)) {
//                                    authorities.add(new SimpleGrantedAuthority(role.get("authority")));
//                                }
//                            }
//                        }
//                        //组装参数
//                        SelfUserEntity selfUserEntity = new SelfUserEntity();
//                        selfUserEntity.setUsername(claims.getSubject());
//                        selfUserEntity.setUserId(Long.parseLong(claims.getId()));
//                        selfUserEntity.setAuthorities(authorities);
//                        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(selfUserEntity, userId, authorities);
//                        SecurityContextHolder.getContext().setAuthentication(authentication);
//                    }

            }else{
                throw new CommonException(EmErrorCode.TOKEN_EXPIRE);
            }
        }
        filterChain.doFilter(request, response);
    }
}
